#include "Protocol.h"
#include "BufMgr.h"
#include "PkgBuf.h"
#include "CustomProt.h"
#include "WebSocketProt.h"

#define PROT_CUSTOM_FLAG 0xA5C3
#define PROT_WEBSOCKET_FLAG "GET "

CProtocol::CProtocol()
{
}

CProtocol::~CProtocol()
{
}

// 通讯协议解析，后续数据以该协议进行解析数据
CProtocol *CProtocol::ProtParse(CBuffer<> *pBuffer, PkgBuf *pbRecv, ProtModule &pm)
{
    int iRead = 0;
    int iBufLen = 0;
    CProtocol *pProt = nullptr;

    if (nullptr == pBuffer || nullptr == pbRecv)
        return nullptr;

    iBufLen = pBuffer->GetDataLength();

    // 如果包缓冲中数据不够两字节，读齐两字节
    if (sizeof(uint16_t) > pbRecv->nCurLen)
    {
        uint16_t nFlag = sizeof(uint16_t) - pbRecv->nCurLen;

        if (iBufLen < nFlag)
            return nullptr;

        iRead = pBuffer->Read(pbRecv->pBuffer + pbRecv->nCurLen, nFlag);
        pbRecv->nCurLen += iRead;
        iBufLen -= iRead;
    }

    pm.iMod = -1;
    pm.pt = ProtType::Invalide;

    if (sizeof(uint16_t) <= pbRecv->nCurLen)
    {
        uint16_t nStartFlg = *(uint16_t *)pbRecv->pBuffer;

        // 初步判断标志
        if (PROT_CUSTOM_FLAG == nStartFlg)
        {
            pProt = CCustomProt::CustomProtParse(pBuffer, pbRecv, pm);
        }
        else
        {
            // 不为自定义协议头的标志，判断是否为websocket头标志
            // 再读两字节，判断是否为:"GET "
            if (iBufLen < 2)
                return nullptr;

            iRead = pBuffer->Read(pbRecv->pBuffer + pbRecv->nCurLen, 2);
            pbRecv->nCurLen += iRead;
            iBufLen -= iRead;

            // 其它协议握手数据的判断
            if (0 == strncasecmp((char *)pbRecv->pBuffer, (char *)PROT_WEBSOCKET_FLAG, 4))
            {
                pProt = CWebSocketProt::WebSocketProtParse(pBuffer, pbRecv, pm);

                if (nullptr == pProt)
                {
                    // 判断是否为http等协议
                }
            }
        }
    }

    return pProt;
}

// CProtocol *CProtocol::CreateProtocol(ProtType pt)
// {
//     CProtocol *prot = nullptr;

//     switch (pt)
//     {
//     case ProtType::Custom:
//         prot = new CCustomProt();
//         break;

//     case ProtType::WebSocket:
//         prot = new CWebSocketProt();
//         break;

//     default:
//         break;
//     }

//     return prot;
// }